import type { ComputedRef, MaybeRef } from 'vue'
import { computed, reactive, unref } from 'vue'
import { TreeUtils } from '@sat/shared-utils'
import type { TableColumn } from '../../../Table'
import type { DescriptionsSchema } from '../../../Descriptions'
import type { FormSchema } from '../types'

interface CrudSearchParams extends Omit<FormSchema, 'field'> {
  // 是否隐藏在查询项
  hidden?: MaybeRef<boolean>
}

interface CrudTableParams extends Omit<TableColumn, 'field'> {
  // 是否隐藏表头
  hidden?: MaybeRef<boolean>
}

interface CrudFormParams extends Omit<FormSchema, 'field'> {
  // 是否隐藏表单项
  hidden?: MaybeRef<boolean>
}

interface CrudDescriptionsParams extends Omit<DescriptionsSchema, 'field'> {
  // 是否隐藏表单项
  hidden?: MaybeRef<boolean>
}

export type CrudSchema = Omit<TableColumn, 'children'> & {
  search?: CrudSearchParams
  table?: CrudTableParams
  form?: CrudFormParams
  detail?: CrudDescriptionsParams
  children?: CrudSchema[]
}

export interface AllSchemas {
  searchSchema: MaybeRef<FormSchema[]>
  tableColumns: MaybeRef<TableColumn[]>
  formSchema: MaybeRef<FormSchema[]>
  detailSchema: MaybeRef<DescriptionsSchema[]>
}

// 过滤所有结构
export function useCrudSchemas(crudSchema: CrudSchema[]): {
  allSchemas: AllSchemas
} {
  // 所有结构数据
  const allSchemas = reactive<AllSchemas>({
    searchSchema: [],
    tableColumns: [],
    formSchema: [],
    detailSchema: [],
  })
  // 过滤 Search 结构
  const filterSearchSchema = computed(() => {
    const searchSchema: FormSchema[] = []
    const length = crudSchema.length

    for (let i = 0; i < length; i++) {
      const schemaItem = crudSchema[i]
      // 判断是否隐藏
      if (!unref(schemaItem?.search?.hidden)) {
        const searchSchemaItem = {
          component: schemaItem?.search?.component || 'Input',
          ...schemaItem.search,
          field: schemaItem.field,
          label: schemaItem.search?.label || schemaItem.label,
        }
        searchSchema.push(searchSchemaItem)
      }
    }

    return searchSchema
  })
  // @ts-ignore
  allSchemas.searchSchema = filterSearchSchema

  // 过滤 table 结构
  const filterTableSchema = computed(() => {
    const tableColumns = TreeUtils.treeMap<CrudSchema, TableColumn>(crudSchema, {
    // @ts-ignore
      conversion: (schema: CrudSchema) => {
        if (!unref(schema?.table?.hidden)) {
          return {
            ...schema,
            ...schema.table,
          }
        }
      },
    })

    // 第一次过滤会有 undefined 所以需要二次过滤
    return TreeUtils.filterTree<TableColumn>(tableColumns, (data) => {
      if (data.children === undefined)
        delete data.children

      return !!data.field
    })
  })
  // @ts-ignore
  allSchemas.tableColumns = filterTableSchema

  // 过滤 form 结构
  const filterFormSchema = computed(() => {
    const formSchema: FormSchema[] = []
    const length = crudSchema.length

    for (let i = 0; i < length; i++) {
      const formItem = crudSchema[i]
      // 判断是否隐藏
      if (!unref(formItem?.form?.hidden)) {
        const formSchemaItem = {
          component: formItem?.form?.component || 'Input',
          ...formItem.form,
          field: formItem.field,
          label: formItem.form?.label || formItem.label,
        }
        formSchema.push(formSchemaItem)
      }
    }
    return formSchema
  })
  // @ts-ignore
  allSchemas.formSchema = filterFormSchema

  // 过滤 descriptions 结构
  const filterDescriptionsSchema = computed(() => {
    const descriptionsSchema: DescriptionsSchema[] = []

    TreeUtils.forEachTree(crudSchema, (schemaItem: CrudSchema) => {
    // 判断是否隐藏
      if (!unref(schemaItem?.detail?.hidden)) {
        const descriptionsSchemaItem = {
          ...schemaItem.detail,
          field: schemaItem.field,
          label: schemaItem.detail?.label || schemaItem.label,
        }
        descriptionsSchema.push(descriptionsSchemaItem)
      }
    })

    return descriptionsSchema
  })
  // @ts-ignore
  allSchemas.detailSchema = filterDescriptionsSchema

  return {
    allSchemas,
  }
}
